#pragma once

#include "Socket.hpp"
#include "InetAddr.hpp"
#include <memory>
#include <unistd.h>
#include <signal.h>
#include <functional>

using callback_t = std::function<std::string(std::string &)>; // &输入输出

// TcpServer : 只负责进行IO
class TcpServer
{
public:
    TcpServer(int port, callback_t cb)
        : _port(port),
          _listensocket(std::make_unique<TcpSocket>()),
          _cb(cb)
    {
        _listensocket->BuildListenSocketMethod(_port);
    }

    void HandlerRequest(std::shared_ptr<Socket> sockfd, InetAddr addr)
    {
        // 短服务
        std::string inbuffer; // 字节流式的队列
        // 一定能读到一个完整的HTTP请求吗？不一定吧
        // 我们不做处理，认为我们读到了一个完整的http request
        // http如何解决粘报问题
        ssize_t n = sockfd->Recv(&inbuffer);
        if (n > 0)
        {
            std::string send_str = _cb(inbuffer);

            sockfd->Send(send_str);
        }
        else if (n == 0)
        {
            LOG(LogLevel::DEBUG) << addr.ToString() << " quit, me too!";
        }
        else
        {
            LOG(LogLevel::DEBUG) << addr.ToString() << " read error, quit!";
        }
        sockfd->Close();
    }

    void Run()
    {
        while (true)
        {
            // 你要得到一个sockfd, client addr
            InetAddr addr;
            auto sockfd = _listensocket->Accept(&addr);
            if (sockfd == nullptr)
                continue;
            LOG(LogLevel::DEBUG) << "获取一个新连接: " << addr.ToString()
                                 << ", sockfd : " << sockfd->SockFd();

            if (fork() == 0)
            {
                _listensocket->Close();
                HandlerRequest(sockfd, addr);
                exit(0);
            }
            sockfd->Close();
        }
    }
    ~TcpServer()
    {
    }

private:
    int _port;
    std::unique_ptr<Socket> _listensocket;
    callback_t _cb;
};